package org.jugile.tomcat;

import java.io.IOException;
import java.security.Principal;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;

import org.apache.catalina.Realm;
import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.Response;
import org.apache.catalina.realm.GenericPrincipal;
import org.apache.catalina.valves.ValveBase;

public class AutoLoginValve extends ValveBase {

    private String trustedIpAddress;
    private String userid;
    private String passwd;
    
    public AutoLoginValve() {
    }

    @Override
    public void invoke(final Request request, final Response response) 
             throws IOException, ServletException {
        final String remoteAddr = request.getRemoteAddr();
        final String forwarded = request.getHeader("X-Forwarded-For");
        //print("AutoLoginValve: " + remoteAddr + " forwarded-for: " + forwarded);
        //print(dumpHeaders(request));
        final boolean isTrustedIp = isTrusted(remoteAddr) || isTrusted(forwarded);
        print("remoteAddr: " + remoteAddr + " forwarded-for: " + forwarded + 
        		", trusted ip: " + trustedIpAddress + ", isTrustedIp: " + isTrustedIp);
        if (isTrustedIp) {
            final String username = userid;
            final String credentials = passwd;
            final List<String> roles = new ArrayList<String>();
            roles.add("client");
            Realm r = request.getContext().getRealm();
            final Principal principal = 
            	new GenericPrincipal(r,username, credentials, roles);
            request.setUserPrincipal(principal);
        }
        
        getNext().invoke(request, response);
    }
    
    private boolean isTrusted(String ip) {
    	if (ip == null) return false;
    	for (String pat : trustedIpAddress.split(",")) {
    		pat = pat.trim();
    		if (ip.startsWith(pat)) return true;
    	}
    	return false;
    }

    public void setTrustedIpAddress(final String trustedIpAddress) {
        print("setTrusedIpAddress: " + trustedIpAddress);
        this.trustedIpAddress = trustedIpAddress;
    }
    public void setUserid(final String userid) {
        print("setUserid: " + userid);
        this.userid = userid;
    }
    public void setPasswd(final String passwd) {
    	print("setPasswd: " + passwd);
        this.passwd = passwd;
    }

    private String dumpHeaders(Request r) {
    	StringBuffer buf = new StringBuffer();
    	Enumeration en = r.getHeaderNames();
    	buf.append("all headers:\n");
    	while (en.hasMoreElements()) {
    		String name = (String)en.nextElement();
    		String value = r.getHeader(name);
    		buf.append("  " + name +"="+value);
    		buf.append("\n");
    	}
    	return buf.toString();
    }
    
    private void print(String msg) {
    	System.out.println(msg);
    }
}
